package br.com.persist.api;

/**
 * Context that holds the volatile variables defined during a script execution.
 * The variables defined on this context maybe or maybe not be persisted.
 */
public interface VolatileContext {

	/**
	 * Define or update the value of the informed variable.
	 * 
	 * @param key
	 *            The variable key, that is the name of the reference on the
	 *            source code.
	 * @param value
	 *            The object referenced by the informed variable. To release a
	 *            variable call the {@link #release(String)} method.
	 */
	void update(String key, Object value);

	/**
	 * Retrieves the value referenced by the informed variable.
	 * 
	 * @param key
	 *            The name of the variable.
	 * @return The value referenced. It can return <code>null</code> if the
	 *         variable is defined but has its value defined to
	 *         <code>null</code>.
	 * @throws ObjectNotFoundException
	 *             If the informed variable is not defined.
	 */
	Object get(String key) throws ObjectNotFoundException;

	/**
	 * Releases the given variable. Subsequent calls to {@link #get(String)}
	 * throws {@link ObjectNotFoundException}.
	 * 
	 * @param key
	 *            The variable to be released.
	 * @throws ObjectNotFoundException
	 *             If the informed variable is not defined.
	 */
	void release(String key) throws ObjectNotFoundException;

	/**
	 * Release all variables of this context.
	 */
	void releaseAll();

	/**
	 * Creates a new subcontext of this context. The following rules must be met
	 * on the subcontext:
	 * <ul>
	 * <li>Variables created directly on the subcontext cannot be accessed by
	 * the containing contexts.</li>
	 * <li>Variables of the containing contexts cannot be accessed by the
	 * subcontext. There is no global variables.</li>
	 * <li>The method {@link #releaseAll()} releases only the variables defined
	 * on the subcontext.</li>
	 * <li>A call to {@link #releaseAll()} on a context address a call to the
	 * same method in all its subcontexts.</li>
	 * <li>There should be no limitations for the number of levels or
	 * subcontexts in the root context and its children contexts.</li>
	 * </ul>
	 * 
	 * @return The created context.
	 */
	VolatileContext createSubContext();

	/**
	 * Destroys the informed sub context releasing its resources.
	 * 
	 * @param subContext
	 *            The context to be destroyed.
	 */
	void destroySubContext(VolatileContext subContext);
}
